package com.tang.websocket.v1;

import com.tang.websocket.v1.handler.WebSocketHandler;
import com.tang.websocket.v1.message.PingMessage;
import com.tang.websocket.v1.message.PongMessage;
import com.tang.websocket.v1.message.TextMessage;
import com.tang.websocket.v1.session.StandardWebSocketSession;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

import javax.annotation.Resource;
import javax.validation.constraints.NotNull;
import javax.websocket.*;
import java.io.IOException;

/**
 * @author Tang
 * @classname WebSocketLife
 * @description [ WebSocket 生命周期类 ]
 * @date 2022/11/28 23:56
 */
public abstract class WebSocketLife implements ApplicationContextAware {

    protected StandardWebSocketSession standardWebSocketSession = null;

    protected WebSocketHandler webSocketHandler = null;

    protected static ApplicationContext applicationContext;

    @Resource
    protected ConverterRegistry converterRegistry;

    @OnOpen
    public void open(@NotNull Session session) {
        this.standardWebSocketSession = new StandardWebSocketSession(converterRegistry);
        this.standardWebSocketSession.initializeNativeSession(session);
        this.webSocketHandler = getWebSocketHandler();
        this.webSocketHandler.onOpen(standardWebSocketSession);
    }

    @OnMessage
    public void message(String message) throws IOException {
        // 心跳消息
        if (PingMessage.isPing(message)) {
            this.standardWebSocketSession.sendMessage(PongMessage.INSTANCE);
            return;
        }
        if (PongMessage.isPong(message)) {
            this.standardWebSocketSession.sendMessage(PingMessage.INSTANCE);
            return;
        }
        TextMessage socketMessage = new TextMessage(message);
        this.webSocketHandler.onMessage(standardWebSocketSession,socketMessage);
    }

    @OnClose
    public void close() {
        this.webSocketHandler.onClose(standardWebSocketSession);
    }

    @OnError
    public void error(Throwable e) {
        this.webSocketHandler.onError(standardWebSocketSession,e);
    }

    /**
     * 一个业务handler
     * @return
     */
    public abstract WebSocketHandler getWebSocketHandler();

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        WebSocketLife.applicationContext = applicationContext;
    }

    public static ApplicationContext getApplicationContext() {
        return applicationContext;
    }
}
